<template>
  <div class="dashboard-container">
    <div class="app-container">
      <el-card v-loading="loading">
        <el-tabs v-model="activeName" @tab-click="handleClick">
          <el-tab-pane label="角色管理" name="role">
            <!-- 新增按钮 -->
            <el-button
              v-if="checkBtnAccess('ROLE_ADD')"
              type="primary"
              size="medium"
              icon="el-icon-plus"
              @click="showDialog = true"
            >新增角色</el-button>
            <!-- 表格 -->
            <el-table
              :data="list"
              style="width: 100%; margin: 15px 0;"
              border
            >
              <el-table-column
                label="序号"
                type="index"
                :index="indexFn"
                width="180"
                align="center"
              />
              <el-table-column
                prop="name"
                label="角色名称"
                width="180"
              />
              <el-table-column
                prop="description"
                label="描述"
              />
              <el-table-column
                label="操作"
                align="center"
              >
                <!-- 作用域插槽 -->
                <template #default="{row}">
                  <el-button
                    type="success"
                    size="small"
                    @click="assignPrem(row.id)"
                  >分配权限</el-button>
                  <el-button
                    type="primary"
                    size="small"
                    @click="edit(row.id)"
                  >编辑</el-button>
                  <el-button
                    type="danger"
                    size="small"
                    @click="del(row.id)"
                  >删除</el-button>
                </template>
              </el-table-column>
            </el-table>
            <!-- 分页 -->
            <el-pagination
              :current-page="page"
              :page-sizes="[1, 2, 3, 4, 5]"
              :page-size="pagesize"
              layout="total, sizes, prev, pager, next, jumper"
              :total="total"
              @size-change="handleSizeChange"
              @current-change="handleCurrentChange"
            />
          </el-tab-pane>
          <el-tab-pane label="公司信息" name="company">
            <el-alert
              title="对公司名称、公司地址、营业执照、公司地区的更新，将使得公司资料被重新审核，请谨慎修改"
              type="info"
              :closable="false"
              show-icon
            />
            <!-- 公司信息表单 -->
            <!-- 表单 -->
            <el-form label-width="120px" style="margin-top:50px">
              <el-form-item label="公司名称">
                <el-input :value="companyForm.name" disabled style="width:400px" />
              </el-form-item>
              <el-form-item label="公司地址">
                <el-input :value="companyForm.companyAddress" disabled style="width:400px" />
              </el-form-item>
              <el-form-item label="邮箱">
                <el-input :value="companyForm.mailbox" disabled style="width:400px" />
              </el-form-item>
              <el-form-item label="备注">
                <el-input :value="companyForm.remarks" type="textarea" :rows="3" disabled style="width:400px" />
              </el-form-item>
            </el-form>
          </el-tab-pane>
        </el-tabs>
      </el-card>
      <!-- 添加 和 编辑 的 弹窗 -->
      <el-dialog :title="roleDialogTitle" :visible="showDialog" @close="btnCancel">
        <el-form ref="roleForm" label-width="80px" :model="form" :rules="rules">
          <el-form-item label="角色名称" prop="name">
            <el-input v-model="form.name" placeholder="请输入角色名称" />
          </el-form-item>
          <el-form-item label="角色描述" prop="description">
            <el-input v-model="form.description" placeholder="请输入角色描述" />
          </el-form-item>
        </el-form>
        <template #footer>
          <el-button type="primary" @click="btnOk">确认</el-button>
          <el-button type="danger" @click="btnCancel">取消</el-button>
        </template>
      </el-dialog>

      <!-- 分配权限 的 弹窗 -->
      <!-- 分配权限的弹层 -->
      <el-dialog title="分配权限" :visible="showAssignDialog" @close="closeAssignDialog">
        <!-- 树形组件 -->
        <el-tree
          ref="tree"
          v-loading="permLoading"
          node-key="id"
          :data="permissionList"
          :props="{label: 'name'}"
          default-expand-all
          show-checkbox
          check-strictly
        />
        <template #footer>
          <el-button @click="closeAssignDialog">取消</el-button>
          <el-button type="primary" @click="btnPermOk">确定</el-button>
        </template>
      </el-dialog>
    </div>
  </div>
</template>

<script>
// 1. 引入接口
import { getRoleList, delRole, addRole, getRoleDetail, updateRole, getCompanyById, assignPerm } from '@/api/setting'
import { getPermissionList } from '@/api/permission'
import { mapGetters } from 'vuex'
import { tranListToTreeData } from '@/utils'
// 引入混入对象
import checkPermission from '@/mixin/checkPermission'
export default {
  name: 'Setting',
  mixins: [checkPermission],
  data() {
    return {
      // 1. 处于活动状态的标签页
      activeName: 'role',
      // 2. 表格的数据(对象数组)
      list: [],
      // 3. 当前页
      page: 1,
      // 4. 每页条数
      pagesize: 3,
      // 5. 总条数
      total: 0,
      // 6. 加载圈
      loading: false,
      // 7. 控制弹窗的显示/隐藏
      showDialog: false,
      // 8. 表单数据对象
      form: {
        name: '', // 角色名称
        description: '' // 角色描述
      },
      // 9. 表单校验的规则对象
      rules: {
        name: [
          { required: true, message: '角色名称不能为空', trigger: ['blur', 'change'] }
        ],
        description: [
          { required: true, message: '角色描述不能为空', trigger: ['blur', 'change'] }
        ]
      },
      // 10.公司信息对象
      companyForm: {
        name: '',
        companyAddress: '',
        mailbox: '',
        remarks: ''
      },
      // 11. 控制分配权限弹窗的显示/隐藏
      showAssignDialog: false,
      // 12. 用于分配权限的角色id
      roleId: null,
      // 13. 权限列表
      permissionList: [],
      // 14. 权限加载圈
      permLoading: false
    }
  },
  computed: {
    ...mapGetters(['companyId']),
    roleDialogTitle() {
      return this.form.id ? '编辑角色' : '添加角色'
    }
  },
  created() {
    this.getRoleList()
  },
  methods: {
    // 1. 获取表格数据
    async getRoleList() {
      this.loading = true
      // 1.1 调用接口
      const { total, rows } = await getRoleList(this.page, this.pagesize)
      // 1.2 赋值
      this.total = total
      this.list = rows
      this.loading = false
    },
    // 2. 每页显示的条数发生变化会触发
    handleSizeChange(val) {
      // console.log(`每页 ${val} 条`)
      // 2.1 更新每页显示的条数
      this.pagesize = val
      // 2.3 让当前页码到第一页
      this.page = 1
      // 2.2 重新拉取数据
      this.getRoleList()
    },
    // 3.当前页发生变化会触发
    handleCurrentChange(val) {
      // console.log(`当前页: ${val}`)
      // 3.1 更新当前页码
      this.page = val
      // 3.2 重新拉取数据
      this.getRoleList()
    },
    // 4. 自定义序号
    indexFn(index) {
      return index + 1 + this.pagesize * (this.page - 1)
    },
    // 5. 删除一条角色
    async del(id) {
      // 5.1 确认删除
      await this.$confirm('确定删除该角色吗?', '温馨提示', { type: 'warning' })
      // 5.2 调用接口
      await delRole(id)
      // 5.3 提示删除成功
      this.$message.success('删除角色成功')
      // 注意: 如果不是第一页 && 当前页只有一条数据 --> 让当前页码-1, 然后再拉取数据
      if (this.page > 1 && this.list.length === 1) {
        this.page--
      }
      // 5.4 重新更新表格数据
      this.getRoleList()
    },
    // 7. 添加/编辑角色
    btnOk() {
      // 7.1 整体校验
      this.$refs.roleForm.validate(async isOk => {
        if (!isOk) return

        // 7.2 判断是添加还是编辑
        if (this.form.id) { // 编辑
          // 调用编辑接口
          await updateRole(this.form)
          this.$message.success('更新角色成功')
        } else { // 添加
          // 调用添加接口
          await addRole(this.form)
          this.$message.success('添加角色成功')
        }

        // 7.3 关闭弹窗, 重新渲染
        this.btnCancel()
        this.getRoleList()
      })
    },
    // 8. 关闭添加/编辑角色弹窗
    btnCancel() {
      this.showDialog = false
      // 8.1 重置form数据对象(添加和编辑一起做的时候,一定要处理)
      this.form = {
        name: '', // 角色名称
        description: '' // 角色描述
      }
      // 8.2 重置表单数据和校验规则
      this.$refs.roleForm.resetFields()
    },
    // 9. 点击编辑按钮
    async edit(id) {
      // 9.1 获取角色详情
      const res = await getRoleDetail(id)
      // 9.2 数据回显
      this.form = res
      // 9.3 打开对话框
      this.showDialog = true
    },
    // 10. 点击切换标签页
    handleClick() {
      if (this.activeName === 'company') {
        if (this.companyForm.id) return
        console.log('进入公司信息版块')
        this.getCompanyById()
      }
    },
    // 11. 获取公司信息
    async getCompanyById() {
      // 11.1 发起请求
      const res = await getCompanyById(this.companyId)
      console.log(res)
      // 11.2 数据回显
      this.companyForm = res
    },
    // 12. 关闭分配权限弹窗
    closeAssignDialog() {
      this.showAssignDialog = false
      // 清空树组件上勾选的复选框
      this.$refs.tree.setCheckedKeys([])
      this.permissionList = []
    },
    // 13. 点击分配权限按钮
    async assignPrem(id) {
      this.permLoading = true
      // 13.1 记录权限id
      this.roleId = id
      // 13.2 展示弹窗
      this.showAssignDialog = true
      // 13.3 获取当前系统中所有的权限
      const res = await getPermissionList()
      this.permissionList = tranListToTreeData(res, '0')
      // 13.4 根据角色的id获取角色所拥有的权限
      const { permIds } = await getRoleDetail(id)
      // 13.5 往树组件上设置权限
      this.$refs.tree.setCheckedKeys(permIds)
      this.permLoading = false
    },
    // 14. 分配权限确定按钮
    async btnPermOk() {
      // 14.1 获取所有的权限数组
      const permIdsArr = this.$refs.tree.getCheckedKeys()
      // console.log(permIdsArr)
      // 14.2 发起请求
      await assignPerm(this.roleId, permIdsArr)
      // 14.3 提示用户
      this.$message.success('更新角色的权限成功')
      // 14.4 关闭弹窗
      this.closeAssignDialog()
    }
  }
}
</script>

<style>

</style>
